Kubernetes 為每個 Service 和 Pod 建立 DNS 記錄 (名稱)。這些 DNS 名稱允許 Pod 之間、Pod 和 Service 之間通過名稱進行通信,而不是依賴 IP 地址。這樣,即使 Pod 或 Service 的 IP 地址變更,通信依然可以通過不變的 DNS 名稱進行。
使用 DNS 來管理 Pod 和 Service 的通信具有以下好處:
Kubernetes 自動為以下情況創建 DNS 條目:
<service-name>.<namespace>.svc.cluster.local
。以下是使用 Service 和 DNS 的組態檔範例:
Common Service
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 8080
Pod 可以通過以下 DNS 名稱訪問這個 Service:
my-service
my-service.default.svc.cluster.local
Headless Service
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
clusterIP: None
selector:
app: MyApp
ports:
- port: 80
targetPort: 8080
None
,定義這是一個 Headless Service。如果是 Headless Service 是綁定 StatefulSet 的 Pod 標籤,這樣每個符合 selector
的 Pod 都會獲得一個 DNS 名稱。透過如 podname.my-headless-service.default.svc.cluster.local
格式的 DNS 名稱訪問個別 Pod。
在不使用 StatefulSet,單純的讓 Pod 想要獲得 DNS 名稱,需要在 Pod 中進行額外設置。
組態檔案: dns-test.yaml
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: foo
name: foo
spec:
hostname: foo-host
subdomain: foo-headless-svc
containers:
- name: foo
image: lofairy/foo
---
apiVersion: v1
kind: Service
metadata:
name: foo-headless-svc
spec:
clusterIP: None
selector:
app: foo
ports:
- protocol: TCP
port: 80
targetPort: 8080
foo
Pod 中額外設置 hostname=foo-host
與 subdomain=foo-headless-svc
。其中 subdomain 需要跟 Headless Service 名稱一致。這樣設置完成後,我們就可以通過 DNS 格式 <hostname>.<subdomain>.default.svc.cluster.local
訪問該 Pod。
kubectl apply -f dns-test.yaml
kubectl run -it --image busybox:1.36 dns-test --restart=Never --rm
foo-clusterip-svc
DNS Recordnslookup foo-host.foo-headless-svc.default.svc.cluster.local
---
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: foo-host.foo-headless-svc.default.svc.cluster.local
Address: 10.244.2.47
Kubernetes 的 Service 和 Pod DNS 系統提供了一種靈活且可靠的方式來管理集群內部的服務和 Pod 之間的通信。通過 DNS 名稱,Kubernetes 確保了服務的穩定性和可訪問性,即使 Pod 的 IP 地址發生變化,也不會影響到整體的系統通信架構。這對於分布式應用和微服務架構尤其重要。